package tr.edu.yildiz.ce.dap.apm.util;

import java.beans.AppletInitializer;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.xml.bind.JAXBException;

import tr.edu.yildiz.ce.dap.acm.service.CacheManagerService;
import tr.edu.yildiz.ce.dap.acm.service.impl.CacheManagerServiceImpl;
import tr.edu.yildiz.ce.dap.acm.util.exception.AlreadyCachedException;
import tr.edu.yildiz.ce.dap.acm.util.exception.CacheCanNotBeFoundException;
import tr.edu.yildiz.ce.dap.acm.util.exception.CacheConfigurationFaultException;
import tr.edu.yildiz.ce.dap.acm.util.exception.CanNotGenerateIDException;
import tr.edu.yildiz.ce.dap.amc.ws.gen.Application;
import tr.edu.yildiz.ce.dap.apm.ProxyProperties;
import tr.edu.yildiz.ce.dap.appagent.exception.AgentDeploymentException;
import tr.edu.yildiz.ce.dap.appagent.model.AppDefinition;
import tr.edu.yildiz.ce.dap.appagent.model.Component;
import tr.edu.yildiz.ce.dap.appagent.model.ComponentList;
import tr.edu.yildiz.ce.dap.appagent.service.DapXmlConverter;

public class AppCache extends TimerTask{

	List<AppDefinition> appDefList = new ArrayList<AppDefinition>();
	List<AppDefinition> autoAppDefList = new ArrayList<AppDefinition>();
	static AppCache instance;
	
	public static AppCache getInstance() {
		return instance;
	}
	
	@Override
	public void run() {
		synchronized (appDefList) {
			AppManagerInitializer.initApplications();
			String folder = ProxyProperties.getInstance().getProxyApps();
			cacheApplications(folder,appDefList);
			cacheComponents(appDefList);
			folder = ProxyProperties.getInstance().getProxyAutoApps();
			cacheApplications(folder,autoAppDefList);
			cacheComponents(autoAppDefList);
		}
	}

	private void cacheComponents(List<AppDefinition> appList) {
		if (ProxyProperties.getInstance().isCachingEnabled()){
			for(AppDefinition appDefinition : appList){
				updateCachedComponentList(appDefinition.getComponentList());
			}
		}
	}

	private void cacheApplications(String folder,List<AppDefinition> appList) {
		File proxyXMLCache = new File(folder);
		File[] files = proxyXMLCache.listFiles(new DapXmlFilter());
		appList.clear();
		for (File file : files) {
			try {
				AppDefinition appDefinition = (AppDefinition) DapXmlConverter.convertToObject(file);
				appList.add(appDefinition);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private void updateCachedComponentList(ComponentList componentList){
		CacheManagerService cmService = new CacheManagerServiceImpl();
		for (Component c : componentList.getComponent()) {
			try {
				c.setUrl(cmService.generateUrl(c));
				cmService.addComponent(c);
			} catch (CacheConfigurationFaultException e) {
				e.printStackTrace();
			} catch (CanNotGenerateIDException e) {
				e.printStackTrace();
			} catch (AgentDeploymentException e) {
				e.printStackTrace();
			} catch (AlreadyCachedException e) {
			}
		}
	}
	
	public List<AppDefinition> getAppDefList() {
		synchronized (appDefList) {
			return appDefList;
		}
	}
	
	public List<AppDefinition> getAutoAppDefList() {
		synchronized (appDefList) {
			return autoAppDefList;
		}
	}
	
	
	public static void start(){
		instance = new AppCache();
		Timer timer = new Timer();
		timer.schedule(instance, 5000);
	}

}
